﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using NORM.DataBase;
using DevelopAssistant.Common;
using DevelopAssistant.Service;
using ICSharpCode.WinFormsUI.Docking;
using DevelopAssistant.Core.ToolBox;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace DevelopAssistant.Core.ToolBar
{
    public partial class LeftMenuBar : DockContent
    {
        string Keywords = string.Empty;

        MainForm _MAINFORM = null;
        ContextMenuStrip contextmenu = null;
        ContextMenuStrip ContextMenu = null;
        TreeNode CurrentDatabaseServer = null;

        delegate void DelegateAddTreeNode(TreeNode ownerNode, TreeNode noneNode);

        Dictionary<string, ToolStripMenuItem> m_ContextMenuItems = new Dictionary<string, ToolStripMenuItem>();

        public LeftMenuBar()
        {
            InitializeComponent();
            InitializeControl();
        }

        public LeftMenuBar(MainForm mainform, System.Windows.Forms.ContextMenuStrip contextmenu)
            : this()
        {
            _MAINFORM = mainform;
            
            //BinaryFormatter bf = new BinaryFormatter();
            //MemoryStream ms = new MemoryStream();
            //bf.Serialize(ms, contextmenu);
            //ms.Seek(0, SeekOrigin.Begin);
            //ContextMenu = (ContextMenuStrip)bf.Deserialize(ms);

            this.contextmenu = contextmenu;

            this.SystemDataBaseTree.Nodes.Clear();
        }
        
        private void InitializeControl()
        {
            SystemDataBaseTree.ItemDrag += new ItemDragEventHandler(TreeNode_ItemDrag); 
        }

        private void LoadContextMenuItems()
        {
            ContextMenu = new ContextMenuStrip();
            m_ContextMenuItems = new Dictionary<string, ToolStripMenuItem>();

            foreach (ToolStripMenuItem item in contextmenu.Items)
            {
                ToolStripMenuItem n_item = new ToolStripMenuItem();
                n_item.Name = item.Name;
                n_item.Text = item.Text;
                n_item.Image = item.Image;
                n_item.AutoSize = true;

                if (item.DropDownItems != null && item.DropDownItems.Count > 0)
                {
                    foreach (ToolStripMenuItem sonitem in item.DropDownItems)
                    {
                        ToolStripMenuItem nn_item = new ToolStripMenuItem();
                        nn_item.Name = sonitem.Name;
                        nn_item.Text = sonitem.Text;
                        nn_item.Image = sonitem.Image;
                        nn_item.AutoSize = true;
                        nn_item.Click += new EventHandler(ContextMenuItem_Click);
                        m_ContextMenuItems.Add(n_item.Name + ">" + nn_item.Name, nn_item);
                        n_item.DropDownItems.Add(nn_item);
                    }
                }

                n_item.Click += new EventHandler(ContextMenuItem_Click);
                m_ContextMenuItems.Add(n_item.Name, n_item);
                ContextMenu.Items.Add(n_item);
            }
        }
              
        private void LeftMenuBar_Load(object sender, EventArgs e)
        {             
            LoadServers();
            LoadContextMenuItems();
        }

        private void ContextMenuItem_Click(object sender, EventArgs e)
        {
            string SnippetCode = null;
            TreeNode SelectedTreeNode = SystemDataBaseTree.SelectedNode;

            ToolStripMenuItem Item = sender as ToolStripMenuItem;

            switch (Item.Text)
            {
                case "连接服务器":
                    DataBaseServer dataBaseServer = SelectedTreeNode.Tag as DataBaseServer;
                    if (!dataBaseServer.OnConnecting)
                    {
                        bool bl = false;
                        string message = string.Empty;
                        dataBaseServer.OnConnecting = true;
                        SystemDataBaseTree.Enabled = false;
                        System.Threading.Thread th = new System.Threading.Thread(() => {
                            ConnectDataBase(dataBaseServer, ref bl, ref message);
                            this.Invoke(new MethodInvoker(delegate() {
                                SystemDataBaseTree.Enabled = true;
                                if (bl)
                                    _MAINFORM.SetSysStatusInfo("完成");
                                else
                                    _MAINFORM.SetSysStatusInfo(message);                            
                            }));                        
                        });
                        th.IsBackground = true;
                        th.Start();

                    }
                    break;
                case "断开连接":
                    DisConnectDataBase();
                    break;
                case "编辑连接":
                case "编辑属性":
                    DataBaseServer dbserver = SelectedTreeNode.Tag as DataBaseServer;
                    EditDataBaseConnection dcnt = new EditDataBaseConnection().EditDataBaseConnectiontor(dbserver, this);
                    dcnt.ShowDialog(this);
                    break;
                case "删除连接":
                    DeleteConnectionDataBase();
                    break;
                case "刷新":
                    RefreshDataBase();
                    break;
            }

            if (_MAINFORM.ConnectedDataBaseServer == null || !_MAINFORM.ConnectedDataBaseServer.OnConnecting)
                return;
           
            switch (Item.Text)
            {
                case "打开表":
                case "打开视图":
                    SnippetCode = Service.SelectTable.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                    _MAINFORM.SetQueryDocumentText(SnippetCode,true);
                    break;
                case "设计表":
                    DevelopAssistant.Core.DBMS.TableDesignnerDocument tableDesignner = new DBMS.TableDesignnerDocument(SelectedTreeNode.Text,_MAINFORM.ConnectedDataBaseServer);
                    _MAINFORM.AddFloatWindow(tableDesignner, "设计" + SelectedTreeNode.Text + "表");
                    break;
                case "生成代码":                     
                    ToolBox.CreateCodePicker codePicker = new ToolBox.CreateCodePicker(SelectedTreeNode.Text, SnippetCode);
                    codePicker.ShowDialog(_MAINFORM);
                    break;
                case "删除表":
                    DevelopAssistant.Core.DBMS.DeleteTableDocument tableDelete = new DBMS.DeleteTableDocument(SelectedTreeNode, _MAINFORM.ConnectedDataBaseServer, this);
                    _MAINFORM.AddFloatWindow(tableDelete, "删除" + SelectedTreeNode.Text + "表");
                    break;
                case "Create 脚本":
                    switch (SelectedTreeNode.Tag + "")
                    {                                           
                        case "table":
                            SnippetCode = Service.CreateTable.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                            break;
                        case "view":
                            SnippetCode = Service.CreateView.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                            break;   
                        case "procedure":
                            SnippetCode = Service.CreateProcedure.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                            break;
                        case "function":
                            SnippetCode = Service.CreateFunction.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                            break;
                        default:
                            SnippetCode = Service.CreateTable.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                            break;
                    }                    
                    _MAINFORM.SetQueryDocumentText(SnippetCode, true);
                    break;
                case "Insert 脚本":
                    SnippetCode = Service.InsertTable.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                    _MAINFORM.SetQueryDocumentText(SnippetCode, true);
                    break;
                case "Clear 脚本":
                    SnippetCode = Service.DeleteTable.ToSnippetCode(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                    _MAINFORM.SetQueryDocumentText(SnippetCode, true);
                    break;
                case "编辑数据":
                    //new DevelopAssistant.Core.DBMS.TableDataEditorDocument(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer).ShowDialog(_MAINFORM);
                    DevelopAssistant.Core.DBMS.TableDataEditorDocument tableDataEditForm = new DevelopAssistant.Core.DBMS.TableDataEditorDocument(SelectedTreeNode.Text, _MAINFORM.ConnectedDataBaseServer);
                    _MAINFORM.AddFloatWindow(tableDataEditForm, "编辑" + SelectedTreeNode.Text + "数据");
                    break;
                case "执行存储过程":
                    ExecuteCommand ProcedureExecute = new ExecuteCommand(SelectedTreeNode.Text, "Procedure", _MAINFORM.ConnectedDataBaseServer);
                    if (ProcedureExecute.ShowDialog(_MAINFORM).Equals(DialogResult.OK))
                        _MAINFORM.SetQueryDocumentText(ProcedureExecute.SqlText, true);
                    break;
                case "执行函数":
                    ExecuteCommand FunctionExecute = new ExecuteCommand(SelectedTreeNode.Text, "Function", _MAINFORM.ConnectedDataBaseServer);
                    if (FunctionExecute.ShowDialog(_MAINFORM).Equals(DialogResult.OK))
                        _MAINFORM.SetQueryDocumentText(FunctionExecute.SqlText, true);
                    break;
            }
        }

        private void treeView1_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                SystemDataBaseTree.SelectedNode = e.Node;
            }
            if (e.Node.ContextMenuStrip == null)
                e.Node.ContextMenuStrip = ContextMenu;

            SetContextMenuItem(e.Node.Level, e.Node.Text, e.Node.Tag+"");
            SelectCurrentDataBaseServer(e.Node);
        }

        private void TreeNode_ItemDrag(object sender, ItemDragEventArgs e)
        {
            TreeNode node = (TreeNode)e.Item;
            if (node.Tag != null && (node.Tag.ToString() == "table") || (node.Tag.ToString() == "view") || (node.Tag.ToString() == "column") ||
             (node.Tag.ToString() == "procedure") || (node.Tag.ToString() == "function"))
            {
                DoDragDrop(node, System.Windows.Forms.DragDropEffects.Copy);
            }
        }

        public bool SetContextMenuItem(int level,string text,string category)
        {
            bool result = false;
            try
            {
                switch (level)
                {
                    case 0:
                        m_ContextMenuItems["连接服务器ToolStripMenuItem"].Visible = true;
                        m_ContextMenuItems["断开连接ToolStripMenuItem"].Visible = true;
                        m_ContextMenuItems["编辑属性ToolStripMenuItem"].Visible = true;
                        m_ContextMenuItems["删除连接ToolStripMenuItem"].Visible = true;
                        m_ContextMenuItems["打开表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["设计表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["删除表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["编辑数据ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["生成脚本ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["生成代码ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["刷新ToolStripMenuItem1"].Visible = true;
                        break;
                    case 1:
                        m_ContextMenuItems["连接服务器ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["断开连接ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["编辑属性ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["删除连接ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["打开表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["设计表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["删除表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["编辑数据ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["生成脚本ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["生成代码ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["刷新ToolStripMenuItem1"].Visible = true;
                        break;
                    case 2:
                        m_ContextMenuItems["连接服务器ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["断开连接ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["编辑属性ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["删除连接ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["打开表ToolStripMenuItem"].Visible = true;

                        switch (category)
                        {
                            case "table":
                                 m_ContextMenuItems["打开表ToolStripMenuItem"].Text = "打开表";
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>insertSQLToolStripMenuItem"].Visible = true;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>updateSQLToolStripMenuItem"].Visible = true;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>clearSQLToolStripMenuItem"].Visible = true;
                                 m_ContextMenuItems["设计表ToolStripMenuItem"].Visible = true;
                                 m_ContextMenuItems["删除表ToolStripMenuItem"].Visible = true;
                                 m_ContextMenuItems["编辑数据ToolStripMenuItem"].Visible = true;
                                break;
                            case "view":
                                 m_ContextMenuItems["打开表ToolStripMenuItem"].Text = "打开视图";
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>insertSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>updateSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>clearSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["设计表ToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["删除表ToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["编辑数据ToolStripMenuItem"].Visible = false;
                                break;
                            case "procedure":
                                 m_ContextMenuItems["打开表ToolStripMenuItem"].Text = "执行存储过程";
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>insertSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>updateSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>clearSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["设计表ToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["删除表ToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["编辑数据ToolStripMenuItem"].Visible = false;
                                break;
                            case "function":
                                 m_ContextMenuItems["打开表ToolStripMenuItem"].Text = "执行函数";
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>insertSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>updateSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["生成脚本ToolStripMenuItem>clearSQLToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["设计表ToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["删除表ToolStripMenuItem"].Visible = false;
                                 m_ContextMenuItems["编辑数据ToolStripMenuItem"].Visible = false;
                                break;
                        }
                       
                        m_ContextMenuItems["生成脚本ToolStripMenuItem"].Visible = true;
                        m_ContextMenuItems["生成代码ToolStripMenuItem"].Visible = true;
                        m_ContextMenuItems["刷新ToolStripMenuItem1"].Visible = true;
                        break;
                    case 3:
                        m_ContextMenuItems["连接服务器ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["断开连接ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["编辑属性ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["删除连接ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["打开表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["设计表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["删除表ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["编辑数据ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["生成脚本ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["生成代码ToolStripMenuItem"].Visible = false;
                        m_ContextMenuItems["刷新ToolStripMenuItem1"].Visible = false;
                        break;
                }
            }
            catch(Exception ex)
            {

            }
           
            return result;
        }

        public int GetContextMemuItemIndex(string name)
        {
            int index = -1;
            for (int i = 0; i < ContextMenu.Items.Count; i++)
            {
                if (ContextMenu.Items[i].Name.ToLower().Equals(name.ToLower()))
                {
                    index = i;
                    break;
                }
            }
            return index;
        }

        public void LoadServers()
        {
            System.Threading.Thread th = new System.Threading.Thread(() => {
                using (var db = NORM.DataBase.DataBaseFactory.Create("default"))
                {
                    string sqlText = "SELECT * FROM [T_DataBaseServers] ORDER BY [id] ASC "; //[dataBaseType] ASC,
                    DataTable dt = db.GetDataSet(System.Data.CommandType.Text, sqlText, null).Tables[0];

                    foreach (DataRow dr in dt.Rows)
                    {
                        DataBaseServer dbs = new DataBaseServer();
                        dbs.ID = dr["connectionID"] + "";
                        dbs.Name = dr["connectionName"] + "";
                        dbs.ProviderName = dr["dataBaseType"] + "";                       
                        dbs.ConnectionString = dr["connectionString"] + "";
                        dbs.Parse();

                        AddDataBaseConnection(dbs, null);
                    }
                }            
            });
            th.IsBackground = true;
            th.Start();
            
        }

        public void AddDataBaseConnection(object Paramater, Delegate CallBack)
        {
            bool Sucess = false; 
            string Message = String.Empty;

            DataBaseServer databaseServer = Paramater as DataBaseServer;

            System.Threading.Thread th = new System.Threading.Thread(() =>
            {               
                TreeNode ServerDataBaseNode = new TreeNode() { ImageIndex = 0 };
                ServerDataBaseNode.SelectedImageIndex = 12;
                ServerDataBaseNode.Tag = databaseServer;
                ServerDataBaseNode.Text = databaseServer.Name;

                TreeNode node_Table = new TreeNode() { Name = "Table", Text = "数据表", Tag = "Table", ImageIndex = 1 };
                TreeNode node_View = new TreeNode() { Name = "View", Text = "数据视图", Tag = "View", ImageIndex = 2 };
                TreeNode node_Function = new TreeNode() { Name = "Function", Text = "函数", Tag = "Function", ImageIndex = 11 };
                TreeNode node_Procedure = new TreeNode() { Name = "Procedure", Text = "存储过程", Tag = "Procedure", ImageIndex = 5 };

                ServerDataBaseNode.Nodes.AddRange(new TreeNode[] { 
                        node_Table,
                        node_View,
                        node_Function,
                        node_Procedure
                    });

                this.Invoke(new MethodInvoker(delegate()
                {                   
                    SystemDataBaseTree.Nodes.Add(ServerDataBaseNode);
                    SystemDataBaseTree.SelectedNode = CurrentDatabaseServer = ServerDataBaseNode;
                }));

                if (databaseServer.OnConnecting)
                    ConnectDataBase(databaseServer, ref Sucess, ref Message);
                if (CallBack != null) CallBack.DynamicInvoke(Message, Message);  

            });

            th.IsBackground = true;
            th.Start();
        }

        public void ConnectDataBase(DataBaseServer databaseServer,ref bool sucess,ref string message,Delegate callback=null)
        {
            if (CurrentDatabaseServer != null && CurrentDatabaseServer.Level == 0)
            {
                TreeNode node_Table = new TreeNode() { Name = "Table", Text = "数据表", Tag = "Table", ImageIndex = 1 };
                TreeNode node_View = new TreeNode() { Name = "View", Text = "数据视图", Tag = "View", ImageIndex = 2 };
                TreeNode node_Function = new TreeNode() { Name = "Function", Text = "函数", Tag = "Function", ImageIndex = 11 };
                TreeNode node_Procedure = new TreeNode() { Name = "Procedure", Text = "存储过程", Tag = "Procedure", ImageIndex = 5 };

                this.Invoke(new MethodInvoker(delegate()
                {
                    CurrentDatabaseServer.Nodes.Clear();
                    CurrentDatabaseServer.Nodes.AddRange(new TreeNode[] { 
                        node_Table,
                        node_View,
                        node_Function,
                        node_Procedure
                    });
                }));

                databaseServer.Tables = new List<Table>();
                databaseServer.Views = new List<DevelopAssistant.Service.View>();
                databaseServer.Procedures = new List<Procedure>();
                databaseServer.Functions = new List<Function>();
                
                try
                {
                    databaseServer.DataBaseServerNode = CurrentDatabaseServer;
                    this.Invoke(new MethodInvoker(delegate()
                    {
                        CurrentDatabaseServer.ExpandAll();
                    }));

                    _MAINFORM.ConnectedDataBaseServer = databaseServer;

                    DelegateAddTreeNode d = new DelegateAddTreeNode(AddTreeNode);

                    var dt = new DataTable();
                    using (var db = Utility.GetAdohelper(databaseServer))
                    {
                        dt = db.GetDataBaseObject();

                        foreach (DataRow dr in dt.Rows)
                        {
                            string table_type = dr["table_type"] + "";
                            string table_name = dr["table_name"] + "";

                            bool matchSuccess = true;
                            if(!string.IsNullOrEmpty(Keywords)&&
                                table_name.IndexOf(Keywords,
                                StringComparison.OrdinalIgnoreCase) < 0)
                            {
                                matchSuccess = false;
                            }

                            if (matchSuccess)
                            {
                                TreeNode node = new TreeNode() { Text = table_name };
                                switch (table_type)
                                {
                                    case "table":
                                        DevelopAssistant.Service.Table t = new DevelopAssistant.Service.Table();
                                        t.Name = table_name;
                                        databaseServer.Tables.Add(t);
                                        node.Tag = "table";
                                        node.ImageIndex = 3;
                                        d.Invoke(node_Table, node);
                                        AddDataBaseObjectItem(node, databaseServer, db);
                                        break;
                                    case "view":
                                        DevelopAssistant.Service.View v = new DevelopAssistant.Service.View();
                                        v.Name = table_name;
                                        databaseServer.Views.Add(v);
                                        node.Tag = "view";
                                        node.ImageIndex = 4;
                                        d.Invoke(node_View, node);
                                        AddDataBaseObjectItem(node, databaseServer, db);
                                        break;
                                    case "function":
                                        DevelopAssistant.Service.Function f = new DevelopAssistant.Service.Function();
                                        f.Name = table_name;
                                        f.Parameters = new List<SqlParameter>();
                                        f.Describtion = "返回类型：" + table_type + "\r\n" + "属于：" + databaseServer.DataBaseName;
                                        DataTable pdt = db.GetTableObject(f.Name);
                                        foreach (DataRow row in pdt.Rows)
                                        {
                                            SqlParameter p1 = new SqlParameter();
                                            p1.Name = row["ColumnName"] + "";
                                            p1.DataType = row["TypeName"] + "";
                                            if (!string.IsNullOrEmpty(p1.Name))
                                                f.Parameters.Add(p1);
                                        }
                                        databaseServer.Functions.Add(f);
                                        node.Tag = "function";
                                        node.ImageIndex = 10;
                                        d.Invoke(node_Function, node);
                                        break;
                                    case "procedure":
                                        DevelopAssistant.Service.Procedure p = new DevelopAssistant.Service.Procedure();
                                        p.Name = table_name;
                                        databaseServer.Procedures.Add(p);
                                        node.Tag = "procedure";
                                        node.ImageIndex = 6;
                                        d.Invoke(node_Procedure, node);
                                        break;
                                } 
                            }
                        }

                    }

                    this.Invoke(new MethodInvoker(delegate()
                    {
                        SystemDataBaseTree.SelectedNode = CurrentDatabaseServer;
                        CurrentDatabaseServer.ImageIndex = 13;                    
                    }));

                    sucess = true;
                    message = "完成";

                    databaseServer.OnConnecting = true;                   

                }
                catch (Exception ex)
                {
                    this.Invoke(new MethodInvoker(delegate()
                    {
                        SystemDataBaseTree.SelectedNode = CurrentDatabaseServer;
                        CurrentDatabaseServer.ImageIndex = 0;                        
                    }));
                    sucess = false;
                    message = ex.Message; //"建立连接时出现与网络相关的或特定于实例的错误";
                }
                finally
                {
                    this.Invoke(new MethodInvoker(delegate() { node_Table.Expand(); }));

                    if (callback != null)
                        callback.DynamicInvoke();
                }

            }
        }

        public void DisConnectDataBase()//DataBaseServer databaseServer
        {
            TreeNode SelectedTreeNode=SystemDataBaseTree.SelectedNode;
            if (SelectedTreeNode.Level == 0)
            {
                SelectedTreeNode.Nodes.Clear();
                SelectedTreeNode.ImageIndex = 0;
                ((DataBaseServer)SelectedTreeNode.Tag).OnConnecting = false;
            }               
        }

        public void DeleteConnectionDataBase()
        {
            TreeNode SelectedTreeNode = SystemDataBaseTree.SelectedNode;
            if (SelectedTreeNode.Level == 0)
            {               
                DataBaseServer dataBaseServer = SelectedTreeNode.Tag as DataBaseServer;
                using (var db = NORM.DataBase.DataBaseFactory.Create("default"))
                {
                    db.BeginTransaction();
                    try
                    {
                        string sqlText = "DELETE FROM [T_DataBaseServers] WHERE [connectionID]='" + dataBaseServer.ID + "'";
                        int val = db.Execute(CommandType.Text, sqlText, null);
                        SelectedTreeNode.Nodes.Clear();
                        SystemDataBaseTree.Nodes.Remove(SelectedTreeNode);
                        db.Commit();
                    }
                    catch (Exception ex)
                    {
                        db.RollBack();
                    }                   
                }
            }          
        }

        public void RefreshDataBase()
        {
            bool _Success = false;
            string _MessageInfo = string.Empty;
            DataBaseServer _DataBaseServer = null;

            SystemDataBaseTree.Enabled = false;

            TreeNode SelectedTreeNode = SystemDataBaseTree.SelectedNode;
            SelectedTreeNode.Nodes.Clear();
            switch (SelectedTreeNode.Level)
            {
                case 0:
                    _DataBaseServer = SelectedTreeNode.Tag as DataBaseServer;
                    _DataBaseServer.OnConnecting = true;
                    ConnectDataBase(_DataBaseServer, ref _Success, ref _MessageInfo, null);
                    break;
                case 1:
                    _DataBaseServer = SelectedTreeNode.Parent.Tag as DataBaseServer;
                    using (var db = Utility.GetAdohelper(_DataBaseServer))
                    {
                        AddDataBaseObject(SelectedTreeNode, _DataBaseServer, db);
                    }
                    break;
                case 2:
                    _DataBaseServer = SelectedTreeNode.Parent.Parent.Tag as DataBaseServer;
                    using (var db = Utility.GetAdohelper(_DataBaseServer))
                    {
                        _DataBaseServer.AllObject = true;
                        if ((SelectedTreeNode.Tag.ToString()) == "table" | (SelectedTreeNode.Tag.ToString()) == "view")
                            AddDataBaseObjectItem(SelectedTreeNode, _DataBaseServer, db);
                        SelectedTreeNode.Expand();
                    }
                    break;
            }

            _MAINFORM.ConnectedDataBaseServer = _DataBaseServer;
            _MAINFORM.SetSysStatusInfo("完成");
            SystemDataBaseTree.Enabled = true;

        }

        public void AddDataBaseObject(TreeNode ownerNode, DataBaseServer dbs, DataBase db)
        {
            DelegateAddTreeNode d = new DelegateAddTreeNode(AddTreeNode);

            DataTable dt = new DataTable();
            string collectionName = "table";
            if (ownerNode.Text == "数据表")
            {
                collectionName = "u";
                dbs.Tables = new List<Table>();
                dt = db.GetDataBaseObject(collectionName);
                foreach (DataRow dr in dt.Rows)
                {
                    string table_type = dr["table_type"] + "";
                    string table_name = dr["table_name"] + "";

                    bool matchSuccess = true;
                    if (!string.IsNullOrEmpty(Keywords) &&
                        table_name.IndexOf(Keywords,
                        StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        matchSuccess = false;
                    }

                    if (matchSuccess)
                    {
                        TreeNode node = new TreeNode() { Text = table_name };
                        node.ImageIndex = 3;
                        node.Tag = "table";
                        Table t = new Table();
                        t.Name = table_name;
                        dbs.Tables.Add(t);
                        d.Invoke(ownerNode, node);
                        AddDataBaseObjectItem(node, dbs, db);
                    }
                   
                }
            }
            else if (ownerNode.Text == "数据视图")
            {
                collectionName = "v";
                dbs.Views = new List<DevelopAssistant.Service.View>();
                dt = db.GetDataBaseObject(collectionName);
                foreach (DataRow dr in dt.Rows)
                {
                    string view_type = dr["table_type"] + "";
                    string view_name = dr["table_name"] + "";

                    bool matchSuccess = true;
                    if (!string.IsNullOrEmpty(Keywords) &&
                        view_name.IndexOf(Keywords,
                        StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        matchSuccess = false;
                    }

                    if (matchSuccess)
                    {
                        TreeNode node = new TreeNode() { Text = view_name };
                        node.ImageIndex = 4;
                        node.Tag = "view";
                        Service.View v = new Service.View();
                        v.Name = view_name;
                        dbs.Views.Add(v);
                        d.Invoke(ownerNode, node);
                        AddDataBaseObjectItem(node, dbs, db);
                    }
                   
                }
            }
            else if (ownerNode.Text == "函数")
            {
                collectionName = "fn";
                dbs.Functions = new List<Service.Function>();
                dt = db.GetDataBaseObject(collectionName);
                foreach (DataRow dr in dt.Rows)
                {
                    string function_type = dr["table_type"] + "";
                    string function_name = dr["table_name"] + "";

                    bool matchSuccess = true;
                    if (!string.IsNullOrEmpty(Keywords) &&
                        function_name.IndexOf(Keywords,
                        StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        matchSuccess = false;
                    }

                    if (matchSuccess)
                    {
                        TreeNode node = new TreeNode() { Text = function_name };
                        node.ImageIndex = 10;
                        node.Tag = "function";
                        Service.Function f = new Service.Function();
                        f.Name = function_name;
                        f.Describtion = "返回类型：" + function_type + "\r\n" + "属于：" + dbs.DataBaseName;
                        DataTable pdt = db.GetTableObject(f.Name);
                        foreach (DataRow row in pdt.Rows)
                        {
                            SqlParameter p1 = new SqlParameter();
                            p1.Name = row["ColumnName"] + "";
                            p1.DataType = row["TypeName"] + "";
                            if (!string.IsNullOrEmpty(p1.Name))
                                f.Parameters.Add(p1);
                        }
                        dbs.Functions.Add(f);
                        d.Invoke(ownerNode, node);
                    }                    
                }
            }
            else if (ownerNode.Text == "存储过程")
            {
                collectionName = "p";
                dbs.Views = new List<DevelopAssistant.Service.View>();
                dt = db.GetDataBaseObject(collectionName);
                foreach (DataRow dr in dt.Rows)
                {
                    string procedure_type = dr["table_type"] + "";
                    string procedure_name = dr["table_name"] + "";

                    bool matchSuccess = true;
                    if (!string.IsNullOrEmpty(Keywords) &&
                        procedure_name.IndexOf(Keywords,
                        StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        matchSuccess = false;
                    }

                    if (matchSuccess)
                    {
                        TreeNode node = new TreeNode() { Text = procedure_name };
                        node.ImageIndex = 6;
                        node.Tag = "procedure";
                        Service.Procedure p = new Service.Procedure();
                        p.Name = procedure_name;
                        dbs.Procedures.Add(p);
                        d.Invoke(ownerNode, node);
                    }

                }
            }           

        }

        public void AddDataBaseObjectItem(TreeNode ownerNode, DataBaseServer dbs, DataBase db)
        {
            var dateItem = new DataObjectEnumerable();
            var dateTable = db.GetTableObject(ownerNode.Text.Trim());
            dateItem = dbs.Tables.Find(w => w.Name == ownerNode.Text.Trim());
            if (dateItem == null)
                dateItem = dbs.Views.Find(w => w.Name == ownerNode.Text.Trim());
            dateItem.Columns = new List<Column>();

            if ((ownerNode.Tag + "") != "table" && (ownerNode.Tag + "") != "view")
                return;

            DelegateAddTreeNode d = new DelegateAddTreeNode(AddTreeNode);

            foreach (DataRow dr in dateTable.Rows)
            {
                string ColumnName = dr["ColumnName"] + "";
                string TypeName = dr["TypeName"] + "";
                string Length = dr["Length"] + "";
                string CisNull = dr["CisNull"] + "";

                bool matchSuccess = true;
                if (!string.IsNullOrEmpty(Keywords) &&
                    ColumnName.IndexOf(Keywords,
                    StringComparison.OrdinalIgnoreCase) < 0)
                {
                    matchSuccess = false;
                }

                if (matchSuccess)
                {
                    bool is_pk = false;
                    if (CisNull.Contains("pk"))
                        is_pk = true;

                    Column c = new Column();
                    c.Name = ColumnName;
                    c.DataType = TypeName;
                    c.Len = Length;
                    c.Description = "数据类型：" + TypeName + "\r\n属于：" + ownerNode.Text;

                    if (dbs.AllObject)
                    {
                        string innerText = ColumnName;
                        string innerLength = Length;
                        if (TypeName != "int" && TypeName != "double"
                            && TypeName != "float" && TypeName != "decimal"
                            && TypeName != "uuid" && TypeName != "text"
                            && TypeName != "integer" && TypeName != "image"
                            && TypeName != "datetime")
                        {
                            innerLength = "(" + Length + ")";
                        }
                        else
                        {
                            innerLength = "";
                        }
                        innerText += "[" + "" + TypeName + "" + innerLength + "]";

                        TreeNode node = new TreeNode() { Text = innerText, Tag = ColumnName, ToolTipText = innerText };
                        node.Tag = "column";

                        if (is_pk)
                            node.ImageIndex = 15;
                        else
                            node.ImageIndex = 9;

                        d.Invoke(ownerNode, node);

                    }

                    dateItem.Columns.Add(c);
                }

            }

        }

        public void AddTreeNode(TreeNode ownerNode, TreeNode noneNode)
        {
            SystemDataBaseTree.Invoke(new MethodInvoker(delegate()
            {
                _MAINFORM.SetSysStatusInfo("添加" + noneNode.Text);  
                ownerNode.Nodes.Add(noneNode);                   
            }));           
        }

        public void SelectCurrentDataBaseServer(TreeNode node)
        {
            switch (node.Level)
            {
                case 0: _MAINFORM.ConnectedDataBaseServer = (DataBaseServer)node.Tag; this.CurrentDatabaseServer = node; break;
                case 1: _MAINFORM.ConnectedDataBaseServer = (DataBaseServer)node.Parent.Tag; this.CurrentDatabaseServer = node.Parent; break;
                case 2: _MAINFORM.ConnectedDataBaseServer = (DataBaseServer)node.Parent.Parent.Tag; this.CurrentDatabaseServer = node.Parent.Parent; break;
                case 3: _MAINFORM.ConnectedDataBaseServer = (DataBaseServer)node.Parent.Parent.Parent.Tag; this.CurrentDatabaseServer = node.Parent.Parent; break;
                case 4: _MAINFORM.ConnectedDataBaseServer = (DataBaseServer)node.Parent.Parent.Parent.Parent.Tag; this.CurrentDatabaseServer = node.Parent.Parent; break;
            }
        }

        public void SetSelectedNode(TreeNode node)
        {          
            this.SystemDataBaseTree.SelectedNode = node;
        }

        public DataBaseServer GetDataBaseServerByConnectionID(string id)
        {
            DataBaseServer _databaseServer = (DataBaseServer)this.CurrentDatabaseServer.Tag;

            foreach (TreeNode servernode in SystemDataBaseTree.Nodes)
            {
                if (servernode.Level == 0 && ((DataBaseServer)servernode.Tag).ID == id)
                {
                    _databaseServer = (DataBaseServer)servernode.Tag;
                }
            }

            return _databaseServer;
        }

        private void SystemDataBaseTree_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            var node = e.Node;
            if (node.Level == 0)
            {
                CurrentDatabaseServer = node;
                var dataBaseServer = CurrentDatabaseServer.Tag as DataBaseServer;
                if (!dataBaseServer.OnConnecting)
                {
                    bool bl = false;
                    string message = string.Empty;
                    dataBaseServer.OnConnecting = true;
                    SystemDataBaseTree.Enabled = false;
                    System.Threading.Thread th = new System.Threading.Thread(() =>
                    {
                        ConnectDataBase(dataBaseServer, ref bl, ref message);
                        this.Invoke(new MethodInvoker(delegate() {
                            SystemDataBaseTree.Enabled = true;
                            if (bl)
                                _MAINFORM.SetSysStatusInfo("完成");
                            else
                                _MAINFORM.SetSysStatusInfo(message);   
                        }));                                                    
                    });
                    th.IsBackground = true;
                    th.Start ();                 
                }
            }
        }

        private void SystemDataBaseTree_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            TreeNode mouseclick_node = SystemDataBaseTree.GetNodeAt(new Point(e.X, e.Y));
            if (mouseclick_node != null && mouseclick_node.Level == 2)
            {
                if (((mouseclick_node.Tag + "") == "table" || (mouseclick_node.Tag+"") == "view")
                    && mouseclick_node.Nodes.Count < 1)
                {
                    DataBaseServer dataBaseServer = (DataBaseServer)_MAINFORM.ConnectedDataBaseServer.Clone();
                    dataBaseServer.AllObject = true;
                    AddDataBaseObjectItem(mouseclick_node, dataBaseServer, DevelopAssistant.Service.Utility.GetAdohelper(_MAINFORM.ConnectedDataBaseServer));
                    _MAINFORM.SetSysStatusInfo("完成");
                    mouseclick_node.Expand(); 
                }
            }
        }

        private void btn_database_refresh_Click(object sender, EventArgs e)
        {
            RefreshDataBase();
        }

        private void btnfilter_Click(object sender, EventArgs e)
        {
            DataBaseTreeFilter filter = new DataBaseTreeFilter(_MAINFORM, this.Keywords);
            if (filter.ShowDialog(_MAINFORM).Equals(DialogResult.OK))
            {
                this.Keywords = filter.Keywords;
                RefreshDataBase();
            }

        }

    }
}
